int num_points = 2;
int num_curr_point = 0;
int num_frame = 0;
int num_gestures = 6;
int num_matches = 0;
int num_level = 0;
int set_round = 60;
boolean console = false;
/*------------------------------------------------------------------------------------------------------------------*/
gPoint[] POINTS = new gPoint[num_points];
Gesture[] GESTURES = new Gesture[num_gestures];
PImage Square,SquareMask;
PImage Triangle,TriangleMask;
PImage P,PMask;
PImage S,SMask;
PImage X,XMask;
PImage Circle,CircleMask;
/*------------------------------------------------------------------------------------------------------------------*/
public void landGesture(int gID, String gName){
//noStroke();
fill(random(255),random(255),random(255),200); 
if (gID==3) {if (touchCursor==true) {touchCursor=false;} else {touchCursor=true;}} 
if (gID==4) {if (paintCursor==true) {paintCursor=false;} else {paintCursor=true;}} 
println("Gesture: "+gID+"-"+gName);   
}
/*------------------------------------------------------------------------------------------------------------------*/
public void drawGestures(float x1, float y1, float x2, float y2)
{
  drawBackground();
  stroke(255,255,255,35);
  //strokeWeight(15);
  //line(mouseX,mouseY,pmouseX,pmouseY);
  line(x1,y1,x2,y2);
 //noStroke(); 
  num_frame++;
  if ( num_frame == 3 )
  {
    POINTS[num_curr_point].setPos(x1,y1);
    num_frame = 0;
    int num_prev_point;
    if ( num_curr_point == 1 ) num_prev_point = 0;
    else num_prev_point = 1;
    float deltax = POINTS[num_curr_point].x - POINTS[num_prev_point].x;
    float deltay = POINTS[num_curr_point].y - POINTS[num_prev_point].y;
    float deltad = sqrt(pow(deltax,2)+pow(deltay,2));
    float deltat = degrees(atan2(deltay,deltax));

    if ( deltax != 0 || deltay != 0 )
    {
      if ( num_matches == 0 )
      {
        num_level = 1;
  
        for ( int i=0; i<num_gestures; i++ )
        {
          if ( checkAlign(deltat,GESTURES[i].dirs[0]) )
          {
            if ( console )
            {
              print("START: ");
              println(GESTURES[i].name);
            }
            GESTURES[i].setTrace(1);
            num_matches++;
          }
        }
      }
      else
      {
        for ( int i=0; i<num_gestures; i++ )
        {
          boolean add_level = false;

          if ( GESTURES[i].traced )
          {
            if ( checkAlign(deltat,GESTURES[i].dirs[num_level]) )
            {
              if ( num_level == GESTURES[i].num_dirs )
              {
                 landGesture(GESTURES[i].id, GESTURES[i].name);
              }
              else
              {
                if ( console )
                {
                  print("NEW: ");
                  println(GESTURES[i].name);
                }
                add_level = true;
              }
            }
            else if ( checkAlign(deltat,GESTURES[i].dirs[num_level-1]) )
            {
              if ( console )
              {
                print("REPEAT: ");
                println(GESTURES[i].name);
              }
            }
            else
            {  
              if ( console )
              {
                print("REMOVE: ");
                println(GESTURES[i].name);
              }
              if ( num_matches > 0 )
              {
                num_matches--;
              }
              GESTURES[i].setTrace(0);
            }
          }
  
          if ( add_level )
          {
            num_level++;
          }
        }
      }
    }
    num_curr_point++;
  }

  if ( num_curr_point == num_points )
  {
    num_curr_point = 0;
  }
}

boolean checkAlign(float A, float B)
{
  boolean X;

  if ( abs(A-B) < set_round/2 )
  {
    X = true;
  }
  else if ( B == 180 && abs(A+B) < set_round/2)
  {
    X = true;
  }
  else
  {
    X = false;
  }

  return X;
} 
/*------------------------------------------------------------------------------------------------------------------*/
void drawBackground()
{
  //stroke(15);
  //fill(#222222);
  //rect(0,0,width,height);
  image(Square,17,50);
  image(P,17,100);
  image(S,17,150);
  image(X,17,200);
  image(Circle,17,250);
  image(Triangle,17,300);
}

public void setupGestures()
{
  rectMode(CORNER);
  GESTURES[0] = new Gesture();
  GESTURES[0].setName("Square");  
  GESTURES[0].setID(0);  
  GESTURES[0].setDir(-90);
  GESTURES[0].setDir(0);
  GESTURES[0].setDir(90); 
  GESTURES[0].setDir(180);
  
  Square = loadImage("Square.jpg");
  SquareMask = loadImage("SquareMask.jpg");
  Square.mask(SquareMask);

  GESTURES[1] = new Gesture();
  GESTURES[1].setName("P");
  GESTURES[1].setID(1);  
  GESTURES[1].setDir(90);
  GESTURES[1].setDir(-45);
  GESTURES[1].setDir(-135); 
  
  P = loadImage("P.jpg");
  PMask = loadImage("PMask.jpg");
  P.mask(PMask);

  GESTURES[2] = new Gesture();
  GESTURES[2].setName("S");
  GESTURES[2].setID(2);  
  GESTURES[2].setDir(-135);
  GESTURES[2].setDir(180);
  GESTURES[2].setDir(135);
  GESTURES[2].setDir(90);
  GESTURES[2].setDir(45);
  GESTURES[2].setDir(0);
  GESTURES[2].setDir(45); 
  GESTURES[2].setDir(90); 
  GESTURES[2].setDir(135);
  GESTURES[2].setDir(180);
  
  S = loadImage("S.jpg");
  SMask = loadImage("SMask.jpg");
  S.mask(SMask);

  GESTURES[3] = new Gesture();
  GESTURES[3].setName("X");
  GESTURES[3].setID(3);  
  GESTURES[3].setDir(135);
  GESTURES[3].setDir(-90);
  GESTURES[3].setDir(45);
  
  X = loadImage("X.jpg");
  XMask = loadImage("XMask.jpg");
  X.mask(XMask);
  
  GESTURES[4] = new Gesture();
  GESTURES[4].setName("Circle");
  GESTURES[4].setID(4);  
  GESTURES[4].setDir(-135);
  GESTURES[4].setDir(180);
  GESTURES[4].setDir(135);
  GESTURES[4].setDir(90);
  GESTURES[4].setDir(45);
  GESTURES[4].setDir(0);
  GESTURES[4].setDir(-45); 
  GESTURES[4].setDir(-90); 
  
  Circle = loadImage("Circle.jpg");
  CircleMask = loadImage("CircleMask.jpg");
  Circle.mask(CircleMask);
  
  GESTURES[5] = new Gesture();
  GESTURES[5].setName("Triangle");
  GESTURES[5].setID(5);  
  GESTURES[5].setDir(180);
  GESTURES[5].setDir(-45);
  GESTURES[5].setDir(45);
  
  Triangle = loadImage("Triangle.jpg");
  TriangleMask = loadImage("TriangleMask.jpg");
  Triangle.mask(TriangleMask);
  
  for ( int i=0; i<num_points; i++ )
  {
    POINTS[i] = new gPoint();
  }
}
/*------------------------------------------------------------------------------------------------------------------*/
class gPoint
{  
  float x;float y;
  void setPos( float X, float Y )
  { x = X; y = Y;}
}
/*------------------------------------------------------------------------------------------------------------------*/
class Gesture
{
  int num_dirs;
  int id;
  float[] dirs = new float[100];
  String name;
  boolean traced;
  Gesture(){  num_dirs = -1;traced = false;}
  void setDir( float Angle ) { num_dirs++;dirs[num_dirs] = Angle;} 
  void setName( String Name ) { name = Name; }
  void setTrace( int Dec ){
    if ( Dec == 1 ) {traced = true;}
    else{traced = false;}
  }
  void setID( int Id ){id = Id;}
//
}
